CONTENTS | INDEX | PREV | NEXT
 LockAddr
 LockAddrB
 TryLockAddr
 TryLockAddrB
 UnlockAddr
 UnlockAddrB


 NAME
  LockAddr    -   Gain Exclusive, Fast semaphore (bit 0)
  LockAddrB   -   Gain Exclusive, Fast semaphore (bit n 0-7)
  TryLockAddr -   Non-Blocking version of LockAddr
  TryLockAddrB    -   Non-Blocking version of LockAddrB
  UnlockAddr  -   Release exclusive semaphore, bit 0
  UnlockAddrB -   Release exclusive semaphore, bit n 0-7

 SYNOPSIS
  void LockAddr(lck);
  void LockAddrB(bitno, lck);
  int r = TryLockAddr(lck);
  int r = TryLockAddrB(bitno, lck);

  void UnlockAddr(lck);
  void UnlockAddrB(bitno, lck);

  long lck[2];

 FUNCTION
  These are custom DICE functions used for inter-task locking semaphores
  in programs that need such functions.  These routines are somewhat
  faster than standard Amiga semaphore routines and take less memory,
  though at the cost of DICE specific.

  To use an inter-task lock one first initializes an lck array to
  0's.  long lck[2]; is an array of two longwords that the lock
  routines will use to perform their stuff.  This array should be
  zero'd only once at program initialization time (the master task
  before any other tasks are created that use it).

  Each lck array may hold up to 8 locks, hence the LockAddrB() calls.
  The non-B calls use lock #0 for simplicity.  For simplicity we
  will only discuss non-B calls.  To gain a lock you may call
  LockAddr() with the address of the lck array (which, being an array,
  does not need the & in the call).  This routine will not return
  until the lock can be obtained.

  You may also use TryLockAddr() to attempt to gain a lock.  The
  return value is:

      -1      Unable to obtain the lock, it is in use
      1       Lock obtained

  To release an obtained lock you call UnlockAddr(lck).  DO NOT RELEASE
  A LOCK YOU DO NOT HAVE!

 EXAMPLE
  /*
   *  This program obtains a lock based at a public message port and
   *  holds it for ten seconds before releasing it.  The public message
   *  port is left in memory (but only exists once no matter how many
   *  programs you run).
   *
   *  To test locking, open up two or more CLI's and run the program
   *  simultaniously (or as close as your fingers can make it) two or
   *  more times.  Only one program will 'have' the lock at a time.
   *
   *  we use AllocMem() so the port survives the program
   */

  #include <exec/types.h>
  #include <exec/ports.h>
  #include <exec/memory.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <assert.h>

  typedef struct {
      struct MsgPort Port;
      long       Lock[2];
  } MyPort;

  extern void *FindPort();
  extern void *CreatePort();
  extern void *AllocMem();

  MyPort *Port;
  short HaveLock;

  int
  brk()
  {
      if (HaveLock)
      UnlockAddr(Port->Lock);
      return(1);      /*  abort   */
  }

  main()
  {
      char *portName = "Lock-Test";

      onbreak(brk);

      Forbid();
      if ((Port = FindPort(portName)) == NULL) {
      MyPort *port;
      port = AllocMem(sizeof(MyPort) + strlen(portName) + 1, MEMF_PUBLIC | MEMF_CLEAR);
      assert(port);

      port->Port.mp_Node.ln_Name = (char *)(port + 1);
      port->Port.mp_Node.ln_Type = NT_MSGPORT;
      strcpy(port->Port.mp_Node.ln_Name, portName);
      AddPort(port);

      Port = port;
      }
      Permit();

      puts("getting lock");
      LockAddr(Port->Lock);
      HaveLock = 1;
      puts("Got the lock!, sleeping for 10 seconds");
      sleep(10);
      UnlockAddr(Port->Lock);
      HaveLock = 0;
      puts("released lock");
      return(0);
  }

 INPUTS
  long *lck;      A pointer to two longwords, initially zero'd

  int bitno;      lock # ... up to 8 independant locks exist for
              each lck structure

 RESULTS
  int r;          (TryLock only), -1 on failure, 1 on success.

 SEE ALSO